package com.skynet.supervision.config;

import com.skynet.supervision.SupervisionApplication;
import lombok.val;
import org.hibernate.validator.HibernateValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.validation.SmartValidator;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.*;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.time.Duration;
import java.util.Objects;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    //本地上传文件路径
    @Value("${skynet.profile}")
    public String FILE_LCAL_PATH;

    //映射路径
    @Value("${skynet.file_mapping_path}")
    public String FILE_MAPPING_PATH;

    /**
     * 本地上传文件映射
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(FILE_MAPPING_PATH)
                .addResourceLocations(FILE_LCAL_PATH);
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedHeaders("*")
                .allowedMethods("*")
                .allowedOrigins("*")
                .maxAge(3600);
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_JSON);
    }
    @Bean("logger")
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    Logger logger(InjectionPoint point) {
        MethodParameter methodParam = point.getMethodParameter();
        Class<?> clazz = methodParam != null ? methodParam.getContainingClass() : SupervisionApplication.class;
        return Objects.requireNonNull(LoggerFactory.getLogger(clazz));
    }

    @Bean("hibernate-validator-factory")
    ValidatorFactory validatorFactory() {
        return Validation.byProvider(HibernateValidator.class)
                .configure()
                .failFast(true)
                .buildValidatorFactory();
    }

    @Primary
    @Bean("hibernate-javax-validator")
    Validator javaxValidator(
            @Qualifier("hibernate-validator-factory") ValidatorFactory factory) {
        return factory.getValidator();
    }

    @Bean
    @Primary
    SmartValidator smartValidator(
            @Qualifier("hibernate-javax-validator") Validator validator) {
        return new SpringValidatorAdapter(validator);
    }

    @Bean
    RestTemplate restTemplate() {
        val out = new RestTemplateBuilder()
                .setConnectTimeout(Duration.ofSeconds(5))
                .setReadTimeout(Duration.ofMinutes(1))
                .defaultMessageConverters()
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();
        // remove xml converter
        out.getMessageConverters().removeIf(it ->
                it instanceof MappingJackson2XmlHttpMessageConverter);
        return out;

    }
}
